﻿using System;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using Comdiv.QWeb.Factory;
using Comdiv.QWeb.Security;
using Comdiv.QWeb.Utils;

namespace Comdiv.QWeb.SystemActions {
	[Action("qweb.actions",
		Help =
			"EN: Enlist actions on server, available to user (some filter parameters provided); RU: Возвращает список всех доступных пользователю действий на сервере (поддерживается несколько параметров для настройки)"
		)]
	public class QWebActionsAction : ActionBase {
		private static readonly DateTime loadstamp = DateTime.Now;

		private ActionDescriptor[] actions;

		[Bind(
			Help = "EN: Regex to exclude action names in result set; RU : регулярное выражение для исключения действий по имени")
		] private string exnamefilter;

		[Bind(
			Help =
				"EN: Regex to exclude action roles in result set; RU : регулярное выражение для исключения действий по по роли")] private string exrolefilter;

		[Bind(
			Help = "EN: Regex to exclude action types in result set; RU : регулярное выражение для исключения действий по типу")] private string extypefilter;

		[Bind(
			Help = "EN: Regex to filter action names in result set; RU : регулярное выражение для фильтрации действий по имени")] private string namefilter;

		[Bind(
			Help = "EN: Regex to filter action roles in result set; RU : регулярное выражение для фильтрации действий по роли")] private string rolefilter;

		[Bind(Default = true,
			Help =
				"EN: if true (by default) - parameters information included; RU: если ДА (по умолчанию) - показывает информацию о параметрах"
			)] private bool showbinders;

		[Bind(
			Help = "EN: Regex to filter action types in result set; RU : регулярное выражение для фильтрации действий по типу")] private string typefilter;

		protected override bool getSupportNotModified() {
			return true;
		}

		protected override string evalEtag() {
			var result = Registry.Factory.GetAllActionTypes().Length + ":" +
			             Context.Parameters.Select(x => string.Format("{0}:{1}", x.Key, x.Value)).concat(";");
			var tag = Convert.ToBase64String(Encoding.UTF8.GetBytes(result));
			return tag;
		}

		protected override DateTime evalLastModified() {
			return loadstamp;
		}

		protected override void prepare() {
			base.prepare();
			var rolechecker = new SimpleActionRoleChecker();
			actions =
				Registry.Factory.GetAllActions()
					.Select(x =>
					        	{
					        		Registry.Factory.ReleaseExecutor(x.Name, x);
					        		return x;
					        	})
					.Where(x => rolechecker.IsAuthorized(Registry, null, x, Context, null))
					.Where(x => namefilter.noContent() || Regex.IsMatch(x.Name, namefilter))
					.Where(x => typefilter.noContent() || Regex.IsMatch(x.ActionTypeName, typefilter))
					.Where(x => exnamefilter.noContent() || !Regex.IsMatch(x.Name, exnamefilter))
					.Where(x => extypefilter.noContent() || !Regex.IsMatch(x.ActionTypeName, extypefilter))
					.Where(x => rolefilter.noContent() || Regex.IsMatch(x.Role, rolefilter))
					.Where(x => exrolefilter.noContent() || !Regex.IsMatch(x.Role, exrolefilter))
					.Select(x =>
					        	{
					        		if (showbinders) {
					        			x.SetupBinders();
					        		}
					        		else {
					        			x.Binders = null;
					        		}
					        		return x;
					        	})
					.ToArray();
		}

		protected override object process() {
			return actions;
		}
	}
}